<?php

class FinalView_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract 
{
    
    /**
    * Zend_Acl object
    * 
    * @var Zend_Acl
    */
    private $_acl;
    
    
    public function __construct(Zend_Acl $acl) 
    {
        $this->_acl = $acl;
    }
    
    /**
     * Called before an action is dispatched by Zend_Controller_Dispatcher.
     *
     * @param  Zend_Controller_Request_Abstract $request
     */
    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        $resource = new FinalView_Acl_Resource
            (
                $request->getModuleName(), 
                $request->getControllerName(), 
                $request->getActionName()
            );
        
        // check ACL only 
        // - when current action can be dispatched 
        // - and ACL resource exists
        if (Zend_Controller_Front::getInstance()->getDispatcher()
            ->isDispatchable($request) && $this->_acl->has($resource)) 
        {
            switch(false) 
            {
                // login
                case Zend_Auth::getInstance()->hasIdentity() : 
                    $this->_login();
                    break;
                
                // forbidden
                case $this->_acl->isAllowed
                    (
                        new Zend_Acl_Role(Zend_Auth::getInstance()
                            ->getIdentity()->role), 
                        $resource
                    ) : 
                    $this->_deny($request);
                    break;
            }
        }
    }
    
    /**
    * Deny access
    * 
    * @param  Zend_Controller_Request_Abstract $request
    */
    protected function _deny(Zend_Controller_Request_Abstract $request) 
    {
        $this->_response->setHttpResponseCode(403);
        $request
            ->setModuleName('default')
            ->setControllerName('error')
            ->setActionName('deny')
            ->setDispatched(false);
    }
    
    /**
    * Redirect to the login action
    * 
    */
    protected function _login() 
    {
        trigger_error(__METHOD__ . ' is not implemented', E_USER_ERROR);
    }
    
}